package com.example.util;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.AnonymousCOSCredentials;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.exception.MultiObjectDeleteException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.DeleteObjectsRequest;
import com.qcloud.cos.model.DeleteObjectsResult;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
import com.qcloud.cos.model.DeleteObjectsRequest.KeyVersion;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class TxOssUtil {

    //用户的 SecretId
    private String secretId;
    //用户的 SecretKey
    private String secretKey;
    // 指定文件将要存放的存储桶
    private String bucketName;
    //存储桶区域信息
    private String regionName;
    //文件夹名称
    private String baseFolder;

    public String upload(MultipartFile multipartFile, String folderName) {
        COSClient client = getOssClient();
        //将MultipartFile类型的文件转为File类型
        File file = null;
        try {
            file = File.createTempFile("temp", null);
            multipartFile.transferTo(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //获取文件的扩展名
        String originalFilename = multipartFile.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String key = baseFolder + "/" + folderName + "/" + UUID.randomUUID().toString() + suffix;

        //封装并上传文件
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
        PutObjectResult putObjectResult = client.putObject(putObjectRequest);

        //返回上传后的路径
        return getUrl(key);
    }

    public String upload(File file, String suffix, String folderName) {
        COSClient client = getOssClient();
        String key = baseFolder + "/" + folderName + "/" + UUID.randomUUID().toString() + suffix;
        //封装并上传文件
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
        PutObjectResult putObjectResult = client.putObject(putObjectRequest);

        //返回上传后的路径
        return getUrl(key);
    }

    public COSClient getOssClient() {
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        Region region = new Region(regionName);
        ClientConfig clientConfig = new ClientConfig(region);

        clientConfig.setHttpProtocol(HttpProtocol.https);
        return new COSClient(cred, clientConfig);
    }

    //获取上传后的访问url地址
    public String getUrl(String key) {
        // 不需要验证身份信息
        COSCredentials cred = new AnonymousCOSCredentials();
        // ClientConfig 中包含了后续请求 COS 的客户端设置：
        ClientConfig clientConfig = new ClientConfig();
        // 设置 bucket 的地域
        // COS_REGION 请参照 https://cloud.tencent.com/document/product/436/6224
        clientConfig.setRegion(new Region(regionName));
        // 设置生成的 url 的请求协议, http 或者 https
        // 5.6.53 及更低的版本，建议设置使用 https 协议
        // 5.6.54 及更高版本，默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);

        // 生成cos客户端
        COSClient cosClient = new COSClient(cred, clientConfig);
        URL url = cosClient.getObjectUrl(bucketName, key);
        System.out.println(url);

        //关闭cos客户端
        cosClient.shutdown();
        return url.toString();
    }

    //删除桶中的对象
    public void deleteObject(String key) {
        key = key.substring(key.indexOf("/") + 1);
        System.out.println("key = " + key);

        COSClient cosClient = getOssClient();
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);
        // 设置要删除的key列表, 最多一次删除1000个
        ArrayList<DeleteObjectsRequest.KeyVersion> keyList = new ArrayList<>();
        // 传入要删除的文件名
        // 注意文件名不允许以正斜线/或者反斜线\开头，例如：
        // 存储桶目录下有a/b/c.txt文件，如果要删除，只能是 keyList.add(new KeyVersion("a/b/c.txt")), 若使用 keyList.add(new KeyVersion("/a/b/c.txt"))会导致删除不成功
        keyList.add(new KeyVersion(key));
        deleteObjectsRequest.setKeys(keyList);

        System.out.println(keyList);

        try {
            DeleteObjectsResult deleteObjectsResult = cosClient.deleteObjects(deleteObjectsRequest);
            List<DeleteObjectsResult.DeletedObject> deleteObjectResultArray = deleteObjectsResult.getDeletedObjects();
        } catch (MultiObjectDeleteException mde) {
            // 如果部分删除成功部分失败, 返回 MultiObjectDeleteException
            List<DeleteObjectsResult.DeletedObject> deleteObjects = mde.getDeletedObjects();
            List<MultiObjectDeleteException.DeleteError> deleteErrors = mde.getErrors();
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        } finally {
            // 确认本进程不再使用 cosClient 实例之后，关闭即可
            cosClient.shutdown();
        }
    }

    public boolean checkExist(String folderName,String fileName) {
        COSClient cosClient = getOssClient();
        // 对象键(Key)是对象在存储桶中的唯一标识
        String key = baseFolder+"/"+folderName+"/"+fileName;
        System.out.println("key = " + key);
        try {
            return cosClient.doesObjectExist(bucketName, key);
        } catch (CosClientException e) {
            e.printStackTrace();
        } finally {
            cosClient.shutdown();
        }
        return false;
    }
}
